/**
 * @Description: 极光推送记录
 * @author ourslookAdmin
 * @date 2019-03-08 18:03:48
 */
import React, { Fragment } from 'react';
import {
  Button,
  Card,
  Checkbox,
  Col,
  Form,
  Icon,
  Input,
  message,
  Radio,
  Row,
  Select,
  Spin,
  Tag,
  Tooltip,
  BackTop,
} from 'antd';
import 'antd/dist/antd.css';
import Modal from 'drag-modal';
import { formatMessage, FormattedMessage } from 'umi/locale';
import PropTypes from 'prop-types';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { connect } from 'dva';
import ReactJson from 'react-json-view';
import { Axis, Chart, Geom, Legend, Tooltip as ChartTooltip } from 'bizcharts';
import DataSet from '@antv/data-set';
import { requestLists, requestPromise } from '@/utils/request';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import Ellipsis from '../../components/ourslook/Ellipsis';
import BaseForm from '../../components/ourslook/BaseForm';
import ETable from '../../components/ourslook/ETable';
import { getWebPath } from '../../utils/request';
import uiUtils, { hasPermission } from '../../utils/uiUtils';
import styles from '../../utils/ourslook.less';

const FormItem = Form.Item;
const Option = Select.Option;
const RadioGroup = Radio.Group;
const TextArea = Input.TextArea;
const Password = Input.Password;
const CheckboxGroup = Checkbox.Group;

const getValue = obj =>
  Object.keys(obj)
    .map(key => obj[key])
    .join(',');

const getSourceTypeMap = {
  '1': '成功',
  '0': '失败',
};

const getErrorCodeMap = {
  '1011': '找不到推送的别名',
  '1005': '推送内容过长',
  '1003': '推送对象不能为空',
  '8888_8888': 'JPUSH服务器异常',
};

const getJpushPlatformOptgroupMap = {
  android: {
    android: 'android',
  },
  ios: {
    ios_all: 'IOS全部',
    ios_apns_production_true: 'IOS生产',
    ios_apns_production_false: 'IOS测试',
  },
};

@connect(() => ({}))
class SysJpushRecord extends React.Component {
  params = {
    page: 1,
    limit: 10,
  };

  formItemLayout = {
    labelCol: { span: 5 },
    wrapperCol: { span: 19 },
  };

  /**
   * https://ant-design.gitee.io/components/table-cn/
   *
   * 需要指定 column 的 width 属性，否则列头和内容可能不对齐。（必须留一列不设宽度或者minWidth以适应弹性布局）
   * 建议指定 scroll.x 为大于表格宽度的固定值或百分比。注意，且非固定列宽度之和不要超过 scroll.x, 一般无table正常展开的宽度
   * 未知长度字段或者字符特别多的字段不要放置在列表
   */
  columns = [
    {
      title: '',
      width: 30,
      align: 'center',
      fixed: 'left',
      render: (value, record, index) => index + 1,
    },
    { title: 'id', dataIndex: 'id', width: 80, align: 'center', sorter: false },
    {
      title: '标题',
      dataIndex: 'title',
      width: 120,
      align: 'center',
      sorter: false,
      render: value => (
        <Ellipsis length={10} tooltip>
          {value}
        </Ellipsis>
      ),
    },
    {
      title: '副标题',
      dataIndex: 'subtitle',
      width: 320,
      align: 'center',
      sorter: false,
      render: value => (
        <Ellipsis length={25} tooltip>
          {value}
        </Ellipsis>
      ),
    },
    {
      title: '推送目标',
      dataIndex: 'audience',
      width: 150,
      align: 'center',
      sorter: false,
      render: value => (
        <Ellipsis length={15} tooltip>
          {value}
        </Ellipsis>
      ),
    },
    { title: '推送平台', dataIndex: 'platform', width: 70, align: 'center', sorter: false },
    { title: '发送编号', dataIndex: 'sendNo', width: 90, align: 'center', sorter: false },
    {
      title: '发送参数',
      dataIndex: 'notification',
      width: 75,
      align: 'left',
      sorter: false,
      render(value, row, index) {
        return (
          <CopyToClipboard
            text={value}
            onCopy={() => message.success(formatMessage({ id: 'ours.curd.list.msg.copySuccess' }))}
          >
            <Tooltip placement="rightTop" title={`${value}`}>
              <Button icon="copy">参数</Button>
            </Tooltip>
          </CopyToClipboard>
        );
      },
    },
    {
      title: '发送时间',
      dataIndex: 'createDate',
      width: 230,
      align: 'center',
      sorter: true,
      key: 'create_date',
    },
    {
      title: '推送失败原因',
      dataIndex: 'errorMsg',
      align: 'center',
      sorter: false,
      render: value => (
        <Ellipsis length={40} tooltip>
          {value}
        </Ellipsis>
      ),
    },
    { title: '错误码', dataIndex: 'errorCode', width: 80, align: 'center', sorter: false },
    {
      title: 'ios环境',
      dataIndex: 'apnsProduction',
      width: 80,
      align: 'center',
      sorter: false,
      fixed: 'right',
      render: (value, record, index) => {
        if (value === 'true') {
          return '生产环境';
        }
        return '测试环境';
      },
    },
    {
      title: 'web端',
      dataIndex: 'webPlatform',
      width: 60,
      align: 'center',
      sorter: false,
      fixed: 'right',
    },
    {
      title: '推送结果',
      dataIndex: 'result',
      width: 60,
      align: 'center',
      fixed: 'right',
      sorter: false,
      render: (value, record, index) =>
        value === 0 ? (
          <Tag style={{ cursor: 'default' }} className={styles.label_danger}>
            失败
          </Tag>
        ) : (
          <Tag style={{ cursor: 'default' }} className={styles.label_success}>
            成功
          </Tag>
        ),
    },
    {
      title: '操作',
      dataIndex: '',
      width: 60,
      align: 'center',
      fixed: 'right',
      render: (value, record, index) => (
        <React.Fragment>
          <a
            onClick={() => {
              this.setStateByTableColume(record, index);
              this.view();
            }}
          >
            <Tooltip title={<FormattedMessage id="ours.curd.list.info" defaultMessage="查看" />}>
              <Icon type="info" />
            </Tooltip>
          </a>
        </React.Fragment>
      ),
    },
  ];

  constructor(props) {
    super(props);
    this.state = {
      showList: 1, //1:显示列表、2:显示新增
      formList: SysJpushRecord.getFormList(),
      selectedRows: [],
      selectedIds: [],
      selectedIndexs: [],
      editModalTitle: null,
      editModalType: null,
      editModel: null,
      editModelConfirmLoading: false,
      //其他属性下面书写
      chartModelVisible: false,
      chartLoading: false,
      chartData: false,
    };
  }

  // 筛选条件
  static getFormList = () => [
    {
      type: 'INPUT',
      field: 'title',
      label: '标题或副标题',
      placeholder: '标题或副标题',
    },
    {
      type: 'DATE',
      field: 'createDate',
      label: '发送时间',
      placeholder: '发送时间',
      format: 'YYYY-MM-DD',
      showTime: false,
    },
    {
      type: 'SELECT',
      field: 'result',
      placeholder: '推送结果',
      initialValue: '',
      list: [{ id: '', name: '请选推送结果' }, ...uiUtils.getOptionJsonObjToArr(getSourceTypeMap)],
    },
    {
      type: 'SELECT',
      field: 'errorCode',
      placeholder: '错误原因',
      initialValue: '',
      list: [{ id: '', name: '请选择错误原因' }, ...uiUtils.getOptionJsonObjToArr(getErrorCodeMap)],
    },
    {
      type: 'SELECT',
      field: 'platform',
      placeholder: '推送平台',
      initialValue: '',
      list: [
        { id: '', name: '请选择推送平台' },
        ...uiUtils.getOptionJsonObjToArr(getJpushPlatformOptgroupMap),
      ],
    },
  ];

  componentDidMount() {
    this.requestList();
  }

  componentWillUnmount() {}

  /**
   * 根据 formItem field 取值 查找formItem
   * @param formItemField obj的field字段
   * @returns 一个对象
   */
  findFormListItemByField = formItemField =>
    this.state.formList.find((value, index, array) => value.field === formItemField);

  query = fieldParams => {
    this.params = JSON.parse(JSON.stringify(Object.assign(this.params, fieldParams)));
    this.requestList();
  };

  view = () => {
    const { selectedRows, selectedIds, selectedIndexs } = this.state;
    if (!selectedRows) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-please' }));
      return;
    }
    if (selectedRows.length > 1) {
      uiUtils.showAlert(formatMessage({ id: 'ours.curd.show-alert.select-one-please' }));
      return;
    }
    this.setState({
      editModalType: 'view',
      editModalTitle: <FormattedMessage id="ours.curd.list.info" defaultMessage="查看" />,
      editModel: selectedRows[0],
      showList: 2,
    });
    this.getInfo(selectedRows[0].id);
  };

  viewChart = () => {
    this.setState({
      chartModelVisible: true,
    });
    this.getChartInfo();
  };

  getInfo = id => {};

  getChartInfo = () => {
    this.setState({
      chartLoading: true,
    });
    requestPromise(getWebPath(`/sys/jpushrecord/chartForBizcharts`), {
      method: 'GET',
    }).then(res => {
      if (res && res.code === 0) {
        this.setState({
          chartData: res.chartData,
        });
      }
      this.setState({
        chartLoading: false,
      });
    });
  };

  setStateByTableColume = (record, index) => {
    this.state = {
      ...this.state,
      selectedRows: [record],
      selectedIds: [record.id],
      selectedIndexs: [index],
    };
  };

  //========其他所有的处理方法，请在按照约定进行处理==========

  /**
   * 表格 筛选和排序 回调
   */
  filtersSorterChange = tableParams => {
    this.params = JSON.parse(JSON.stringify(Object.assign(this.params, tableParams)));
    this.requestList();
  };

  requestList = () => {
    requestLists(this, `${getWebPath('/sys/jpushrecord/list')}`, this.params);
  };

  vShow = showListNum => ({ display: this.state.showList === showListNum ? 'block' : 'none' });

  render() {
    const style = {
      style: {
        marginLeft: 10,
        marginTop: 10,
      },
      disabled: this.state.selectedIndexs.length <= 0,
    };

    /* eslint-disable react/jsx-no-bind */
    return (
      <PageHeaderWrapper title="">
        <Card
          bordered={false}
          style={{ ...this.vShow(1) }}
          className={styles.oursCard}
          bodyStyle={{ padding: '20px' }}
        >
          <BaseForm
            formList={this.state.formList}
            loading={this.state.loading}
            filterSubmit={this.query}
          />
          <Fragment>
            <Button
              type="primary"
              icon="info-circle"
              onClick={this.viewChart}
              hidden={!hasPermission('sys:jpushrecord:info')}
            >
              查看图表
            </Button>
          </Fragment>

          <div className="content-wrap">
            <ETable
              onSelectRow={uiUtils.onSelectRow.bind(this)}
              primaryKey="id"
              selectedIndexs={this.state.selectedIndexs}
              selectedRows={this.state.selectedRows}
              selectedIds={this.state.selectedIds}
              onChange={this.filtersSorterChange}
              columns={this.columns}
              dataSource={this.state.list}
              pagination={this.state.pagination}
              loading={this.state.loading}
              scroll={{ x: 1950 }}
            />
          </div>
        </Card>

        <BackTop />

        <Spin spinning={this.state.editModelConfirmLoading} delay={10}>
          {//返回null,这里对不用的组件进行销毁
          this.state.showList === 1 ? null : (
            <Card
              title={this.state.editModalTitle}
              bordered={false}
              actions={[
                <div>
                  <React.Fragment>
                    <Button
                      type="primary"
                      hidden={this.state.editModalType === 'view'}
                      style={{ marginRight: '18px' }}
                      onClick={this.saveOrUpdate}
                    >
                      <FormattedMessage id="ours.curd.add.save" defaultMessage="保存" />
                    </Button>
                    <Button
                      style={{ marginRight: '18px' }}
                      onClick={() => {
                        this.editForm.props.form.resetFields();
                        this.setState({ showList: 1 });
                      }}
                    >
                      <FormattedMessage id="ours.curd.add.back" defaultMessage="返回" />
                    </Button>
                  </React.Fragment>
                </div>,
              ]}
              style={{ ...this.vShow(2) }}
              bodyStyle={{ padding: '20px' }}
              ref={node => {
                this.container = node;
              }}
            >
              <EditForm
                type={this.state.editModalType}
                model={this.state.editModel}
                wrappedComponentRef={inst => {
                  this.editForm = inst;
                }}
              />
            </Card>
          )}
        </Spin>

        {/*查看推送记录📈(对话框)的对话框*/}
        <PushRecordLineChartsDialog
          dialogVisible={this.state.chartModelVisible}
          chartLoading={this.state.chartLoading}
          chartData={this.state.chartData}
        />
      </PageHeaderWrapper>
    );
  }
}

export default SysJpushRecord;

/**
 *  新增、编辑、复制、查看的Form
 */

/* eslint react/no-multi-comp:0 */
class EditForm extends React.Component {
  static propTypes = {
    type: PropTypes.string, //form类型，可选值：add（增加）、update（修改）、copy（复制）、view（查看）、
    model: PropTypes.object, //数据模型model，对应后台的model
  };

  static defaultProps = {
    type: '', //表单布局数组
    model: null,
  };

  constructor(props) {
    super(props);
    this.state = {};
  }

  /**
   * 生命周期-属性发生变化...componentWillReceiveProps
   * 这里的nextProps，可以获取到所有的属性。
   * 目前没用，因为 dialog 每次都被销毁了
   */
  componentWillReceiveProps(nextProps) {
    if (nextProps.model) {
      this.state = {};
      //使用setFieldsValue实现修改form value的值，不用使用 this.setState({});
      this.props.model.xxx = 'value';
      this.props.form.setFieldsValue({ xxx: 'value' });
    }
  }

  getPropsByKey = prop => {
    const model = this.props.model || {};
    const finalModel = Object.assign(model, this.props.form.getFieldsValue());
    return finalModel[prop];
  };

  render() {
    const type = this.props.type; //编辑是：新增（add）、编辑(edit)、复制(copy)、还是查看(view)
    const model = this.props.model || {};
    const { getFieldDecorator } = this.props.form;
    const formItemLayout = {
      labelCol: { span: 5 },
      wrapperCol: { span: 18 }, //5+19=24,少一个栅格
    };
    const colSpanLayout = { md: 12, sm: 24 }; //每一col跨?列
    const rowGutterPxLayout = { md: 24, sm: 16 }; //col之间的间隔?px
    const inputCodeDisabled = {
      disabled: type === 'update',
    };
    //校验文档：https://ant.design/components/form-cn/#%E6%A0%A1%E9%AA%8C%E8%A7%84%E5%88%99
    return (
      <Form layout="horizontal">
        <Row gutter={{ ...rowGutterPxLayout }}>
          <Col {...colSpanLayout}>
            <FormItem label="id" {...formItemLayout}>
              {type === 'view'
                ? model.id
                : getFieldDecorator('id', {
                    initialValue: model.id,
                  })(
                    <Input type="text" autocomplete="off" {...inputCodeDisabled} placeholder="" />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="标题" {...formItemLayout}>
              {type === 'view'
                ? model.title
                : getFieldDecorator('title', {
                    initialValue: model.title,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={5000}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="副标题" {...formItemLayout}>
              {type === 'view'
                ? model.subtitle
                : getFieldDecorator('subtitle', {
                    initialValue: model.subtitle,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={5000}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="发送时间" {...formItemLayout}>
              {type === 'view'
                ? model.createDate
                : getFieldDecorator('createDate', {
                    initialValue: model.createDate,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      placeholder="发送时间"
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送结果" {...formItemLayout}>
              {type === 'view'
                ? model.result
                : getFieldDecorator('result', {
                    initialValue: model.result,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      placeholder="推送结果"
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送平台" {...formItemLayout}>
              {type === 'view'
                ? model.platform
                : getFieldDecorator('platform', {
                    initialValue: model.platform,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送目标" {...formItemLayout}>
              {type === 'view'
                ? model.audience
                : getFieldDecorator('audience', {
                    initialValue: model.audience,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={65535}
                      placeholder="推送目标"
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送appKey" {...formItemLayout}>
              {type === 'view'
                ? model.appKey
                : getFieldDecorator('appKey', {
                    initialValue: model.appKey,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送appSecert" {...formItemLayout}>
              {type === 'view'
                ? model.appSecert
                : getFieldDecorator('appSecert', {
                    initialValue: model.appSecert,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="错误原因" {...formItemLayout}>
              {type === 'view'
                ? model.errorCode
                : getFieldDecorator('errorCode', {
                    initialValue: model.errorCode,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="推送失败原因" {...formItemLayout}>
              {type === 'view'
                ? model.errorMsg
                : getFieldDecorator('errorMsg', {
                    initialValue: model.errorMsg,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={2000}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="sendNo" {...formItemLayout}>
              {type === 'view'
                ? model.sendNo
                : getFieldDecorator('sendNo', {
                    initialValue: model.sendNo,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
          <Col {...colSpanLayout}>
            <FormItem label="ios环境" {...formItemLayout}>
              {type === 'view'
                ? model.apnsProduction
                : getFieldDecorator('apnsProduction', {
                    initialValue: model.apnsProduction,
                  })(
                    <Input
                      type="text"
                      autocomplete="off"
                      {...inputCodeDisabled}
                      maxlength={255}
                      placeholder=""
                    />
                  )}
            </FormItem>
          </Col>
        </Row>
        <Row gutter={{ ...rowGutterPxLayout }}>
          <Col md={24}>
            <FormItem label="发送参数" {...{ labelCol: { span: 2 }, wrapperCol: { span: 22 } }}>
              {type === 'view' ? (
                <ReactJson
                  src={JSON.parse(model.notification)}
                  theme="apathy"
                  iconStyle="circle"
                  collapsed
                  displayDataTypes={false}
                />
              ) : (
                getFieldDecorator('notification', {
                  initialValue: model.notification,
                })(
                  <Input
                    type="text"
                    autocomplete="off"
                    {...inputCodeDisabled}
                    maxlength={-1}
                    placeholder="发送参数"
                  />
                )
              )}
            </FormItem>
          </Col>
        </Row>
      </Form>
    );
  }
}

/* eslint-disable no-class-assign */
//无更多的绑定， 请用 @Form.create() 注解替换
EditForm = Form.create({})(EditForm);

/*查看推送记录📈(对话框)的对话框*/
//https://bizcharts.net/products/bizCharts/demo/detail?id=line-series&selectedKey=%E6%8A%98%E7%BA%BF%E5%9B%BE
class PushRecordLineChartsDialog extends React.Component {
  static propTypes = {
    dialogVisible: PropTypes.bool,
    chartLoading: PropTypes.bool,
    chartData: PropTypes.array,
  };

  static defaultProps = {
    dialogVisible: false,
    chartLoading: false,
    chartData: [],
  };

  constructor(props) {
    super(props);
    this.state = {
      dialogVisible: this.props.dialogVisible, //dialog visible
      chartLoading: this.props.chartLoading, //network loading
      chartData: this.props.chartData || [],
    };
  }

  /**
   * 生命周期-属性发生变化...componentWillReceiveProps
   * 这里的nextProps，可以获取到所有的属性。
   * 目前没用，因为 dialog 每次都被销毁了
   */
  componentWillReceiveProps(nextProps) {
    if (nextProps.chartData && nextProps.dialogVisible) {
      this.state = {
        chartData: nextProps.chartData || [],
        dialogVisible: nextProps.dialogVisible || false,
        chartLoading: nextProps.chartLoading || false,
      };
    }
  }

  render() {
    const ds = new DataSet();
    const data = this.state.chartData || [];
    const dv = ds.createView().source(data);
    dv.transform({
      type: 'fold',
      fields: ['iosSuccess', 'iosFail', 'androidSuccess', 'androidFail', 'allSuccess', 'allFail'],
      // 展开字段集
      key: 'city',
      // key字段
      value: 'times', // value字段
    });
    const cols = {
      date: {
        range: [0, 1],
      },
    };

    return (
      <Spin spinning={this.state.chartLoading} delay={10}>
        <Modal
          width={800}
          visible={this.state.dialogVisible}
          title="最近15天推送记录图表"
          onCancel={() => {
            this.setState({
              dialogVisible: false,
            });
          }}
          saveDistance={0}
          footer={null}
        >
          <div>
            <Chart height={400} data={dv} scale={cols} forceFit>
              <Legend />
              <Axis name="date" />
              <Axis
                name="times"
                label={{
                  formatter: val => `${val}次`,
                }}
              />
              <ChartTooltip
                crosshairs={{
                  type: 'y',
                }}
              />
              <Geom type="line" position="date*times" size={2} color="city" />
              <Geom
                type="point"
                position="date*times"
                size={4}
                shape="circle"
                color="city"
                style={{
                  stroke: '#fff',
                  lineWidth: 1,
                }}
              />
            </Chart>
          </div>
        </Modal>
      </Spin>
    );
  }
}
